home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / components / flockBlogWebServiceAtom.js < prev    next >
Text File  |  2007-10-12  |  15KB  |  449 lines

  1. // BEGIN FLOCK GPL
  2. // 
  3. // Copyright Flock Inc. 2005-2007
  4. // http://flock.com
  5. // 
  6. // This file may be used under the terms of of the
  7. // GNU General Public License Version 2 or later (the "GPL"),
  8. // http://www.gnu.org/licenses/gpl.html
  9. // 
  10. // Software distributed under the License is distributed on an "AS IS" basis,
  11. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. // for the specific language governing rights and limitations under the
  13. // License.
  14. // 
  15. // END FLOCK GPL
  16. //
  17.  
  18. const Cc = Components.classes;
  19. const Ci = Components.interfaces;
  20.  
  21. const nsISupports           = Ci.nsISupports;
  22. const nsIXMLHttpRequest       = Ci.nsIXMLHttpRequest;
  23.  
  24. const XMLHTTPREQUEST_CONTRACTID   = '@mozilla.org/xmlextras/xmlhttprequest;1';
  25. const FLOCK_ATOM_CID        = Components.ID('{0c01e44c-a61e-4e44-8dee-151d99c54dcf}');
  26. const FLOCK_ATOM_CONTRACTID     = '@flock.com/blog/service/atom;1';
  27. const FLOCK_ATOM_DESCRIPTION    = 'ATOM Blog API';
  28.  
  29. const FLOCK_BLOG_RDF_SETTINGS     = 'urn:flock:blog:settings';
  30.  
  31. function loadLibraryFromSpec(aSpec) {
  32.   var loader = Cc['@mozilla.org/moz/jssubscript-loader;1']
  33.     .getService(Ci.mozIJSSubScriptLoader);
  34.  
  35.   loader.loadSubScript(aSpec);
  36. }
  37.  
  38. loadLibraryFromSpec("chrome://browser/content/flock/blog/atom.js");
  39. loadLibraryFromSpec("chrome://browser/content/flock/blog/technoratiTags.js");
  40. loadLibraryFromSpec("chrome://browser/content/flock/blog/blogBackendLib.js");
  41.    
  42.  
  43. // nsISimpleEnumerator implementation
  44. function simpleEnumerator (aArray) {
  45.   aArray.hasMoreElements = function () { 
  46.     return this.length != 0; 
  47.   }
  48.   aArray.getNext = function () { 
  49.     return this.shift (); 
  50.   }
  51.   return aArray;
  52. }
  53.  
  54. // CONSTRUCTOR 
  55. function atomWebService () {
  56.   this.mQueue = null;
  57.  
  58.   // set attributes
  59.   this.configurationDialog = null;
  60.   this.name = 'ATOM';
  61.   this.shortName = 'atom';
  62.   this.description = "The Atom Publishing Protocol"
  63.   this.supportsCategories = 0;
  64.   this.supportsPostReplace = true;
  65.  
  66.   // Logger
  67.   // this.logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger); 
  68.   // this.logger.init("blog");
  69.   // The logger is buggy?
  70.   this.logger = {};
  71.   this.logger.info = function(txt) { debug("Atom:info:"+txt+"\n"); };
  72.   this.logger.error = function(txt) { debug("Atom:error:"+txt+"\n"); };
  73. }// END CONSTRUCTOR
  74.  
  75. // the nsISupports implementation
  76. atomWebService.prototype.QueryInterface = function (iid) {
  77.   if (iid.equals(Ci.flockICustomBlogWebService) ||
  78.       iid.equals(Ci.flockIBlogWebService) || 
  79.       iid.equals(Ci.nsIClassInfo) || 
  80.       iid.equals(Ci.nsISupports)) {
  81.     return this;
  82.   }
  83.  
  84.   throw Components.results.NS_ERROR_NO_INTERFACE;
  85. }
  86.  
  87. // PRIVATE METHODS  
  88.  
  89. atomWebService.prototype.doRequest = function(listener, method, url, body, processor, aUsername, aPassword) {
  90.   var inst = this;
  91.   this._req = Cc[XMLHTTPREQUEST_CONTRACTID].createInstance(nsIXMLHttpRequest);
  92.   this._req.onreadystatechange = function (aEvt) {
  93.     inst.logger.info("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  94.     inst.logger.info("Request readyState: "+inst._req.readyState+"\n");
  95.     if(inst._req.readyState == 4) {
  96.       inst.logger.info("Request status: "+inst._req.status+"\n");    
  97.       inst.logger.info("\nRESPONSE\n" + inst._req.responseText);
  98.       try {
  99.         if(inst._req.status == 200 || inst._req.status == 201 || inst._req.status == 205) {
  100.         try {
  101.             processor(listener, inst);
  102.           }
  103.           catch(e) {
  104.             // listener.onError(inst.ERROR_PARSER);
  105.             inst.logger.error(e + " " + e.lineNumber+"\n");
  106.           }
  107.         }
  108.         else {
  109.           var faultString; //: "Make sure that are not trying to blog really weird html, and note the following kind user:\n\n",
  110.           // };
  111.           faultString = inst._req.responseText;
  112.           //faultString += inst._req;
  113.         inst.logger.error(faultString+"\n");
  114.         listener.onFault(faultString);
  115.         }
  116.       } catch(e) {
  117.         inst.logger.error(e + " " + e.fileName + " " + e.lineNumber + "\n");
  118.         listener.onError(inst.ERROR_PARSER);
  119.       }
  120.     }
  121.   };
  122.   rval = this._req.open(method, url, true, aUsername, aPassword);
  123.   this.logger.info(">>>>>>>>>> Atom API: FLOCK TO SERVER");
  124.   this.logger.info("\nSENDING\n" + body);
  125.   this.logger.info("\nTO\n" + method + " @ " + url);
  126.   rval = this._req.send(body); 
  127. }
  128.  
  129.  
  130. atomWebService.prototype.parseUsersBlogs = function(listener, inst) {
  131.     debug("atomWebService.prototype.parseUsersBlogs\n");
  132.     var result = new Array();
  133.     var dom = inst._req.responseXML;
  134.     var domEntries = dom.getElementsByTagName("entry");
  135.  
  136.     if (domEntries.length > 0) { // Regular ATOM feed (ATOM)
  137.       for (i=0; i<domEntries.length; i++) {
  138.         debug("One entry...\n");
  139.         domEntry = domEntries[i];
  140.         title = domEntry.getElementsByTagName("title")[0].textContent;
  141.         var newAccount = new BlogAccount(title);
  142.         newAccount.api = this.shortName;
  143.         var links = domEntry.getElementsByTagName("link");
  144.         for (j=0; j<links.length; j++) {
  145.           var link = links[j]
  146.           switch (link.getAttribute("rel")) {
  147.             case "alternate":
  148.               newAccount.URL = link.getAttribute("href");
  149.               break;
  150.             case "http://schemas.google.com/g/2005#post":
  151.               newAccount.apiLink = link.getAttribute("href");
  152.               break;
  153.           }
  154.         }
  155.         result.push(newAccount);
  156.       }
  157.     }
  158.     else { // Just a list of links (Livejournal)
  159.       var links = dom.getElementsByTagName("link");
  160.       var result = new Array();
  161.       for(var i=0;i<links.length;++i) {
  162.         var link = links[i];
  163.         var title = link.getAttribute("title");
  164.         var rel = link.getAttribute("rel");
  165.         var href = link.getAttribute("href");
  166.         switch (rel) {
  167.         case "service.post":
  168.           href.match(/.+\/(.+)/);
  169.           var newAccount = new BlogAccount(title);
  170.           newAccount.api = this.shortName;
  171.           newAccount.blogid = RegExp.$1;
  172.           newAccount.apiLink = href;
  173.           newAccount.editLink = href;
  174.           result.push(newAccount);
  175.           break;
  176.         case "alternate":
  177.           for (j in result)
  178.           if (result[j].title == title)
  179.             result[j].URL = href;
  180.           break;
  181.         default: ;
  182.         }
  183.       }
  184.     }
  185.     debug("Found "+ result.length +" blogs\n");
  186.     listener.onResult(simpleEnumerator(result));
  187. }
  188.  
  189.  
  190. atomWebService.prototype.parseRecentPosts = function(listener, inst) {
  191.   var dom = inst._req.responseXML;
  192.   var entries = dom.getElementsByTagName("entry");
  193.  
  194.   var result = new Array();
  195.   for(var i=0;i<entries.length;++i) {
  196.     try {
  197.       var entry_n = entries[i];
  198.       var title_n = inst.getNamedChild(entry_n, "title");
  199.       var created_n = inst.getNamedChild(entry_n, "published");
  200.       var link_n = null;
  201.       var permalink_n = null;
  202.       var atomid_n = inst.getNamedChild(entry_n, "id");
  203.       var atomid = "";
  204.       if(atomid_n) atomid = atomid_n.firstChild.nodeValue;
  205.  
  206.       for(var j=0;j<entry_n.childNodes.length;++j) {
  207.         if(entry_n.childNodes[j].nodeName=="link") {
  208.           var tmp = entry_n.childNodes[j];
  209.           if(tmp.getAttribute("rel").match(/edit/)) {
  210.             link_n = tmp;
  211.           }
  212.           if(tmp.getAttribute("rel").match(/alternate/)) {
  213.             permalink_n = tmp;
  214.           }
  215.         }
  216.       }
  217.  
  218.       var permaLink = permalink_n.getAttribute("href");
  219.       var href = link_n.getAttribute("href");
  220.       href.match(/.+\/(.+)/);
  221.       var postid = RegExp.$1;
  222.  
  223.       var date = created_n.firstChild.nodeValue;
  224.  
  225.       var post = new BlogPost();
  226.       post.title = title_n.firstChild.nodeValue;
  227.       post.issued = date;
  228.       post.postid = atomid;
  229.       result.push(post);
  230.     }
  231.     catch(e) {
  232.       var logger = Cc['@flock.com/logger;1']
  233.         .getService(Ci.flockILogger);
  234.       logger.error(e + " " + e.lineNumber + " " + e.fileName);
  235.     }
  236.   }
  237.   listener.onResult(simpleEnumerator(result));
  238. }
  239.  
  240. atomWebService.prototype.getNamedChild = function(node, name) {
  241.   for(var i=0;i<node.childNodes.length;++i) {
  242.     if(node.childNodes[i].nodeName==name)
  243.       return node.childNodes[i];
  244.   }
  245.   return null;
  246. }
  247.  
  248. atomWebService.prototype.handleDelete = function(listener, inst) {
  249.   listener.onResult(1);
  250. }
  251.  
  252. function atomListener(aListener){
  253.   this.listener = aListener;
  254.   this.logger = Cc['@flock.com/logger;1']
  255.     .getService(Ci.flockILogger);
  256.   this.logger.init("blog");
  257. }
  258.  
  259. atomListener.prototype = {
  260.   onResult: function(aResult) {
  261.     debug("atomListener, onResult\n");
  262.     var link = aResult.link ? aResult.link : "";
  263.     this.listener.onResult(link);
  264.   },
  265.   onError: function(error) {
  266.     this.logger.error("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  267.     this.logger.error("ERROR "+error+"\n");
  268.     this.listener.onError(error);
  269.   }, 
  270.   onFault: function(error) {
  271.     this.logger.error("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  272.     this.logger.error("FAULT "+error+"\n");
  273.     this.listener.onFault(error);
  274.   } 
  275. }
  276.  
  277. // END PRIVATE METHODS 
  278.  
  279.  
  280. // the flockIBlogWebService implementation 
  281.  
  282. atomWebService.prototype.detectAccount = function (aUrl, aLinkList){
  283.   while(aLinkList.hasMoreElements()) {
  284.     var link = aLinkList.getNext();
  285.     link.QueryInterface(Ci['flockIBlogLink']);
  286.     debug("   ATOM link.href : "+link.href+"\n");
  287.     if(link.type=="application/atom+xml" && link.rel=="service.post") {
  288.       var account = {
  289.         api : "atom",
  290.         apiLink : link.href
  291.       };
  292.       if (account.apiLink.match(/livejournal/)) {
  293.         debug("Forcing default Livejournal API link.\n");
  294.         account.apiLink = "http://www.livejournal.com/interface/atom";
  295.       }
  296.       return account; 
  297.     }
  298.   }
  299.   return null;
  300. }
  301.  
  302.  
  303. atomWebService.prototype.newPost = function (aListener, aBlogId, aPost, aPublish, aNotifications){
  304.   var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci['flockIBlogService']);
  305.   var listener = new atomListener(aListener);
  306.   var atomEntry = {title: aPost.title, content: aPost.description};
  307.   var account = gBlogService.getAccount(aBlogId);
  308.  
  309.   var labels = new Array();
  310.   if (aPost.tags)
  311.     while (aPost.tags.hasMore())
  312.       labels.push(aPost.tags.getNext());
  313.   if (labels.length > 0)
  314.     atomEntry.categories = labels;
  315.   flockAtomPost (listener, account.apiLink, atomEntry,
  316.                  new Array(account.username, account.password));
  317. }
  318.  
  319. atomWebService.prototype.editPost = function (aListener, aBlogAccount, aPostid, aTitle, aDescription, aTags, aDateCreated, aPublish, aEditURI, aAtomID, aNotifications){
  320.   var listener = new atomListener(aListener);
  321.   var atomEntry = { id: aAtomID, title: aTitle, content: aDescription, issued: aDateCreated};
  322.   var labels = new Array();
  323.   while (aTags.hasMore())
  324.     labels.push(aTags.getNext());
  325.   if (labels.length > 0)
  326.     atomEntry.categories = labels;
  327.   flockAtomEdit (listener, aEditURI, atomEntry,
  328.                  new Array(aBlogAccount.username, aBlogAccount.password));
  329. }
  330.  
  331. atomWebService.prototype.deletePost = function (aListener, aBlogAccount, aPostid){
  332.   var url = aBlogAccount.apiLink;
  333.   url += "/" + aPostid;
  334.   // if(aEditURI) url = aEditURI;
  335.   this.doRequest(aListener,"DELETE", url, null, this.handleDelete, aBlogAccount.username, aBlogAccount.password);
  336. }
  337.  
  338. atomWebService.prototype.setPostCategories = function (aListener, aAccount, aPostid, aCategories){
  339.   aListener.onResult(null);
  340. }
  341.  
  342. atomWebService.prototype.getPost = function (aListener, aAccount, aPostid){
  343.   var url = aAccount.apiLink;
  344.   if(aPostid) url += "/" + aPostid;
  345.   var myListener = {
  346.     onResult: function(aResult) {
  347.       var rval = aResult[0];
  348.       aListener.onResult(rval);
  349.     },
  350.     onError: function(aError) {
  351.       aListener.onError(aError);
  352.     },
  353.     onFault: function(aFault) {
  354.       aListener.onFault(aFault);
  355.     },
  356.   };
  357.   this.doRequest(myListener,"GET", url, null, this.parseRecentPosts, aBlogAccount.username, aBlogAccount.password);
  358. }
  359.  
  360. atomWebService.prototype.getUsersBlogs = function (aListener, aAccount){
  361.   //var url = aAccount.apiLink.match(/(.+)\//);
  362.   //url = RegExp.$1;
  363.   url = aAccount.apiLink;
  364.   debug("getUsersBlog... "+url+"\n");
  365.   this.doRequest(aListener,"GET", url, null, this.parseUsersBlogs, aAccount.username, aAccount.password);
  366. }
  367.  
  368. atomWebService.prototype.getRecentPosts = function (aListener, aBlogId, aNumber){
  369.   var blogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService);
  370.   var account = blogService.getAccount(aBlogId);
  371.  
  372.   var url = account.apiLink; 
  373.   //url.match(/(.+\/)(.+)/);
  374.   //if(RegExp.$2=="post") {
  375.   //  url = RegExp.$1 + "feed";
  376.   //}
  377.   debug("getRecentPosts with url = "+url+"\n");
  378.   this.doRequest(aListener, "GET", url, null, this.parseRecentPosts, account.username, account.password);
  379. }
  380.  
  381. atomWebService.prototype.getCategoryList = function (aListener, aAccount){
  382.   aListener.onResult(null);
  383. }
  384.  
  385. atomWebService.prototype.flags = Ci.nsIClassInfo.SINGLETON;
  386. atomWebService.prototype.contractID = FLOCK_ATOM_CONTRACTID;
  387. atomWebService.prototype.classDescription = "Flock ATOM API Service";
  388. atomWebService.prototype.getInterfaces = function (count) {
  389.   var interfaceList = [Ci.flockIWebService,
  390.     Ci.flockICustomBlogWebService,
  391.     Ci.flockIBlogWebService,
  392.       Ci.nsIClassInfo,
  393.       Ci.nsISupports];
  394.   count.value = interfaceList.length;
  395.   return interfaceList;
  396. }
  397. atomWebService.prototype.getHelperForLanguage = function (count) {return null;}
  398.  
  399. // Module implementation
  400. var AtomModule = new Object();
  401.  
  402. AtomModule.registerSelf =
  403. function (compMgr, fileSpec, location, type) {
  404.   compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
  405.  
  406.   compMgr.registerFactoryLocation(FLOCK_ATOM_CID, 
  407.                   "Flock Blogger JS Component",
  408.                   FLOCK_ATOM_CONTRACTID, 
  409.                   fileSpec, 
  410.                   location,
  411.                   type);
  412.   //necessary category registration
  413.   var catmgr = Cc["@mozilla.org/categorymanager;1"]
  414.     .getService (Ci.nsICategoryManager);
  415.   catmgr.addCategoryEntry('flockICustomBlogWebService', 'atom', FLOCK_ATOM_CONTRACTID, true, true);
  416. }
  417.  
  418. AtomModule.getClassObject =
  419. function (compMgr, cid, iid) {
  420.   if (!cid.equals(FLOCK_ATOM_CID))
  421.     throw Components.results.NS_ERROR_NO_INTERFACE;
  422.   
  423.   if (!iid.equals(Ci.nsIFactory))
  424.     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  425.   
  426.   return AtomServiceFactory;
  427. }
  428.  
  429. AtomModule.canUnload =
  430. function(compMgr) {
  431.   return true;
  432. }
  433.   
  434. /* factory object */
  435. var AtomServiceFactory = new Object();
  436.  
  437. AtomServiceFactory.createInstance =
  438. function (outer, iid) {
  439.   if (outer != null)
  440.     throw Components.results.NS_ERROR_NO_AGGREGATION;
  441.  
  442.   return (new atomWebService()).QueryInterface(iid);
  443. }
  444.  
  445. /* entrypoint */
  446. function NSGetModule(compMgr, fileSpec) {
  447.   return AtomModule;
  448. }
  449.